#include "lauxlib.h"
#include "lua.h"
#include "lua_obj.h"
#include "lvgl/lvgl.h"


#define META_ARC "arc"

static int scr_act(lua_State *L)
{
    lv_obj_t *lv_obj = lv_arc_create(lv_scr_act());
    lua_pushlightuserdata(L, (void *)lv_obj);

    luaL_setmetatable(L, META_ARC);
    return 1;
}

static int lua_lv_arc_set_start_angle(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t start = luaL_checkinteger(L, 2);
    lv_arc_set_start_angle(lv_obj, start);
    return 1;
}

static int lua_lv_arc_set_end_angle(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t end = luaL_checkinteger(L, 2);
    lv_arc_set_end_angle(lv_obj, end);
    return 1;
}

static int lua_lv_arc_set_angles(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t start = luaL_checkinteger(L, 2);
    uint16_t end = luaL_checkinteger(L, 3);
    lv_arc_set_angles(lv_obj, start, end);
    return 1;
}

static int lua_lv_arc_set_bg_start_angle(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t start = luaL_checkinteger(L, 2);
    lv_arc_set_bg_start_angle(lv_obj, start);
    return 1;
}

static int lua_lv_arc_set_bg_end_angle(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t end = luaL_checkinteger(L, 2);
    lv_arc_set_bg_end_angle(lv_obj, end);
    return 1;
}

static int lua_lv_arc_set_bg_angles(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t start = luaL_checkinteger(L, 2);
    uint16_t end = luaL_checkinteger(L, 3);
    lv_arc_set_bg_angles(lv_obj, start, end);
    return 1;
}

static int lua_lv_arc_set_rotation(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t rotation = luaL_checkinteger(L, 2);
    lv_arc_set_rotation(lv_obj, rotation);
    return 1;
}

static int lua_lv_arc_set_mode(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    lv_arc_mode_t type = luaL_checkinteger(L, 2);
    lv_arc_set_mode(lv_obj, type);
    return 1;
}

static int lua_lv_arc_set_value(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    int16_t value = luaL_checkinteger(L, 2);
    lv_arc_set_value(lv_obj, value);
    return 1;
}

static int lua_lv_arc_set_range(lua_State *L)
{
    lv_obj_t *lv_obj = (lv_obj_t *)lua_touserdata(L, 1);

    uint16_t min = luaL_checkinteger(L, 2);
    uint16_t max = luaL_checkinteger(L, 3);
    lv_arc_set_range(lv_obj, min, max);
    return 1;
}

static int help(lua_State *L);

static const struct luaL_Reg arraylib_f[] = {
    {"scr_act", scr_act},
    {"help", help},
    {NULL, NULL}};

static const struct luaL_Reg arraylib_m[] = {
    {"set_start_angle", lua_lv_arc_set_start_angle},
    {"set_end_angle", lua_lv_arc_set_end_angle},
    {"set_angles", lua_lv_arc_set_angles},
    {"set_bg_start_angle", lua_lv_arc_set_bg_start_angle},
    {"set_bg_end_angle", lua_lv_arc_set_bg_end_angle},
    {"set_bg_angles", lua_lv_arc_set_bg_angles},
    {"set_rotation", lua_lv_arc_set_rotation},
    {"set_mode", lua_lv_arc_set_mode},
    {"set_value", lua_lv_arc_set_value},
    {"set_range", lua_lv_arc_set_range},
    {"center", lua_lv_obj_center},
    {"align", lua_lv_obj_align},
    {"size", lua_lv_obj_size},
    {"width", lua_lv_obj_set_width},
    {"height", lua_lv_obj_set_height},
    {"pos", lua_lv_obj_set_pos},
    {"x", lua_lv_obj_set_x},
    {"y", lua_lv_obj_set_y},
    {"obj_del", lua_lv_obj_del},
    {NULL, NULL}};

static int help(lua_State *L)
{
    uint16_t n = sizeof(arraylib_m) / sizeof(struct luaL_Reg);

    for (int i = 0; i < n - 1; i++)
    {
        printf("%s\r\n", arraylib_m[i].name);
    }
    return 1;
}

LUALIB_API int lua_lv_arc_funinit(lua_State *L)
{
    luaL_newlib(L, arraylib_f);
    lua_pushnumber(L, LV_ALIGN_CENTER);
    lua_setfield(L, -2, "LV_ALIGN_CENTER");
    luaL_newmetatable(L, META_ARC);  /* create metatable for file handles */
    lua_pushvalue(L, -1);            /* push metatable */
    lua_setfield(L, -2, "__index");  /* metatable.__index = metatable */
    luaL_setfuncs(L, arraylib_m, 0); /* add file methods to new metatable */
    lua_pop(L, 1);                   /* pop new metatable */

    return 1;
}
